﻿
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using System.Diagnostics;

using NeedsMoreNinja.EventManager;

namespace SunXNA.CameraManager
{
    class CCameraManager : IEventListener<SStep>
    {
        #region Public Types

        public class CameraHandle
        {
            private UInt32 m_uid;
            private CCameraManager m_container;

            public CameraHandle(UInt32 uid, CCameraManager container)
            {
                m_uid = uid;
                m_container = container;
            }

            public UInt32 UID
            {
                get { return m_uid; }
            }

            public BaseCamera.CBaseCamera Camera
            {
                get
                {
                    return m_container.GetCamera(this);
                }
            }
        }

        #endregion

        #region Private Member Variables

        private Dictionary<UInt32, BaseCamera.CBaseCamera> m_cameraMap;
        private UInt32 m_lastUID;

        #endregion

        #region Public Accessors
        #endregion

        #region Public Member Functions

        public CCameraManager()
        {
            CEventManager<SStep>.AddListener(this);
            m_cameraMap = new Dictionary<UInt32, SunXNA.CameraManager.BaseCamera.CBaseCamera>();
            m_lastUID = 0;
        }

        public BaseCamera.CBaseCamera GetCamera(CameraHandle handle)
        {
            BaseCamera.CBaseCamera outCamera = null;
            if (m_cameraMap.TryGetValue(handle.UID, out outCamera))
            {
                return outCamera;
            }
            else
            {
                return null;
            }
        }

        public CameraHandle NewCamera<TType>() where TType : BaseCamera.CBaseCamera, new()
        {
            BaseCamera.CBaseCamera newCamera = new TType();
            m_cameraMap.Add(m_lastUID, newCamera);
            return new CameraHandle(m_lastUID++, this);
        }

        public void DeleteCamera(CameraHandle handle)
        {
            Trace.Assert(m_cameraMap.ContainsKey(handle.UID));

            m_cameraMap.Remove(handle.UID);
        }

        public void Handle(SStep e)
        {
            foreach (KeyValuePair<UInt32, BaseCamera.CBaseCamera> pair in m_cameraMap)
            {
                pair.Value.Step(e.gameTime);
            }
        }

        #endregion
    }
}

